package com.demo.springboot;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * ApplicationContextInitializer接口是在spring容器执行refreshed之前的一个回调
 * 使用步骤：
 * 1. 写一个类实现ApplicationContextInitializer接口
 * 2. 注册ApplicationContextInitializer的实现类
 *
 * 注册方法：
 *  1.SpringApplication.addInitializers()
 *  2.通过配置文件(application.properties)中配置context.initializer.classes=实现类全称，可以指定多个，中间用逗号隔开
 *  3.通过spring.factories机制 (META-INF/spring.factories)配置org.springframework.context.ApplicationContextInitializer=实现类全称
 *
 *  CommandLineRunner 接口是Spring容器启动之后的最后一步的回调（类似于开机自启动）
 *
 *  使用步骤：
 *  1.写一个类实现CommandLineRunner接口
 *  2.并将该类放入到Spring的容器中
 *  注：可以通过@Order或者Ordered接口来控制执行顺序
 *
 *  CommandLineRunner 和 ApplicationRunner 区别
 *  传入参数不一样
 *      CommandLineRunner 为 原始参数
 *      ApplicationRunner 为 ApplicationArguments 参数，是对原始参数做了进一步封装
 *      ApplicationArguments是对参数（main方法）的进一步封装
 *      可以解析 --name=value,通过name来获取value
 */
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(App.class);
        //app.addInitializers(new MyApplicationContextInitializer());
        ConfigurableApplicationContext context =  app.run(args);
        ApplicationArguments arguments = context.getBean(ApplicationArguments.class);
        System.out.println(arguments.getSourceArgs().length);
        System.out.println(arguments.getOptionNames());
        System.out.println(arguments.getOptionValues("foo"));
        context.close();

    }
}
